import { goto } from '../goto';
import ajax, { Fetcher } from 'uni-ajax'
import { TaDataUser } from '../data/user';
import { TaCache, TaToast, TaLoading } from './tools';

// 执行队列
let _tasks: any[] = []
let _status: boolean = true

// 创建请求实例，检查登录状态及业务异常，返回 Body 内容
export const TaHttp = ajax.create({ baseURL: import.meta.env.APP_HTTP || '' })

// 创建请求实例，不检查登录状态及业务异常，返回 Body 内容
export const TaAjax = ajax.create({ baseURL: import.meta.env.APP_HTTP || '' })

// 添加请求拦截器
TaHttp.interceptors.request.use(useRequestConfig, error => Promise.reject(error))
TaAjax.interceptors.request.use(useRequestConfig, error => Promise.reject(error))

// 添加响应拦截器
TaHttp.interceptors.response.use(response => useResponseConfig(response, true), error => Promise.reject(error))
TaAjax.interceptors.response.use(response => useResponseConfig(response, false), error => Promise.reject(error))

// 通用 POST 提交，检查登录状态及业务异常，返回 Body 内容，可中断请求
export function TaPost(uri: string, data: any = {}, load: string = ''): Promise<any> {
	load.length > 0 && TaLoading.show(load, true)
	return new Promise((resolve, reject) => {
		if (_status) {
			const fetcher = new Fetcher()
			fetcher.source().then((task: any) => _tasks.push(task))
			TaHttp.post(uri, data, { fetcher }).then((ret: any) => {
				ret.code === 1 ? resolve(ret) : reject(ret)
			}).finally(() => {
				load.length > 0 && TaLoading.hide()
				fetcher.source().then((task: any) => {
					_tasks.splice(_tasks.indexOf(task), 1)
				})
			})
		} else {
			load.length > 0 && TaLoading.hide()
			reject({ code: 0, info: '请求已被阻止！' })
		}
	})
}

// 阻止 POST 请求 ( 十毫秒内阻止请求 )
export function TaAbortPosts(): Promise<any> {
	_status = false;
	_tasks.forEach((x: any, i: number) => (x.abort(), _tasks.splice(i, 1)))
	return new Promise(resolve => setTimeout(() => resolve(_status = true), 10))
}

// 定义请求拦截函数
function useRequestConfig(config: any) {
	let token = TaCache.get('auth.token')
	token && (config.header['Api-Token'] = token)
	config.header['Content-Type'] = 'application/x-www-form-urlencoded'
	return config
}

// 定义结果拦截函数
function useResponseConfig(response: any, checkLogin: boolean = true) {
	// 处理异常状态
	let body = response.data || { code: 0, info: 'unknow', data: {} }
	if (response.statusCode === 404) {
		TaToast.error(body.info || '资源不存在！', true)
		return Promise.reject(body)
	} else if (response.statusCode === 500) {
		TaToast.error(body.info || '服务异常！', true)
		return Promise.reject(body)
	} else if (response.statusCode !== 200) {
		TaToast.error(body.info || '请求异常！' + body.code, true)
		return Promise.reject(body)
	} else if (checkLogin && body.code === 402) {
		TaAbortPosts(), TaToast.error(body.info || '需要完善资料！', true).then(() => goto.bind())
		return Promise.reject(body)
	} else if (checkLogin && (body.code === 401 || body.code === 403)) {
		TaAbortPosts(), TaToast.error(body.info || '需要登录授权！', true).then(() => TaDataUser.logout())
		return Promise.reject(body)
	} else if (checkLogin && body.code !== 1) {
		body.info && TaToast.error(body.info, true)
		return Promise.reject(body)
	}
	// 保存授权令牌
	if (body.data && typeof body.data.token === 'string') {
		TaCache.set('auth.token', body.data.token)
	}
	// 返回主体内容
	return Promise.resolve(body);
}